/**
    Copyright (c) 2010 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#include "DXUT.h"
#include "BuddhabrotBase.h"

/**
*/
BuddhabrotBase::BuddhabrotBase() : m_vCenter( 0.010000007f, 0.22500016f ), m_fZoomScale( 1.0f )
{
}

/**
*/
BuddhabrotBase::~BuddhabrotBase()
{
}

/**
*/
void BuddhabrotBase::TranslateCenter( const D3DXVECTOR2& vDeltaCenter )
{    
    m_vCenter += ( vDeltaCenter * m_fZoomScale );
}

/**
*/
void BuddhabrotBase::ZoomScale( const float fDeltaScale )
{
    m_fZoomScale *= fDeltaScale;
    if( m_fZoomScale == 0.0f ) {
        m_fZoomScale = 0.000001f;
    }
}

/**
*/
void BuddhabrotBase::UpdateConstantBuf( int nInputWidth, int nInputHeight, int nOutputWidth, int nOutputHeight )
{
#define    MIN_RE    -2.0f
#define MAX_RE    2.0f
//#define MIN_IM    -1.2f
#define MIN_IM    -2.0f

    // decide the bounds of the complex number plane
    m_cb.fMinRe = ( MIN_RE ) + m_vCenter.x;
    m_cb.fMaxRe = ( MAX_RE ) + m_vCenter.x;
    m_cb.fMinIm = ( MIN_IM ) + m_vCenter.y;
    // maintain same width/height ratio as the data buffer
    m_cb.fMaxIm = m_cb.fMinIm+(m_cb.fMaxRe-m_cb.fMinRe)*nOutputHeight/nOutputWidth;

    // zoomed
    m_cb.fMinReZoom = ( MIN_RE * m_fZoomScale ) + m_vCenter.x;
    m_cb.fMaxReZoom = ( MAX_RE * m_fZoomScale ) + m_vCenter.x;
    m_cb.fMinImZoom = ( MIN_IM * m_fZoomScale ) + m_vCenter.y;
    // maintain same width/height ratio as the data buffer
    m_cb.fMaxImZoom = m_cb.fMinImZoom+(m_cb.fMaxReZoom-m_cb.fMinReZoom)*nOutputHeight/nOutputWidth;

    // input buffer's dim
    m_cb.nInputWidth = nInputWidth;
    m_cb.nInputHeight = nInputHeight;

    // output buffer's dim
    m_cb.nOutputWidth = nOutputWidth;
    m_cb.nOutputHeight = nOutputHeight;

    // precalculate consts for the buddhabrot plot iteration
    m_cb.fReC = static_cast< float >( nOutputWidth )/(m_cb.fMaxReZoom-m_cb.fMinReZoom);
    m_cb.fImC = static_cast< float >( nOutputHeight )/(m_cb.fMaxImZoom-m_cb.fMinImZoom);

    // determine the largest iteration among the nebulabrot rgb iterations maxs
    m_cb.nMaxIteration = max( max( m_cb.maxIterations[ 0 ], m_cb.maxIterations[ 1 ] ), m_cb.maxIterations[ 2 ] );
}